package org.niux.AutoLoginQQ.operate;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.niux.AutoLoginQQ.VO.QQNumVO;
import org.niux.AutoLoginQQ.common.Constant;
import org.niux.AutoLoginQQ.ui.Main;

/**
 * 所有任务接口 其他任务必须继承访类
 * 
 * @author obullxl
 */
public class SendPollTask implements Runnable {
	private Log log = LogFactory.getLog(this.getClass());

	/* 产生时间 */
	private Date generateTime = null;
	/* 提交执行时间 */
	private Date submitTime = null;
	/* 开始执行时间 */
	private Date beginExceuteTime = null;
	/* 执行完成时间 */
	private Date finishTime = null;

	private long taskId;

	private Main gui;

	private QQNumVO qqNumVO;
	
	private String psessionid;
	
	public SendPollTask(QQNumVO qqNumVO, Main gui,String psessionid) {
		this.generateTime = new Date();
		this.qqNumVO = qqNumVO;
		this.gui = gui;
		this.psessionid = psessionid;
	}

	/**
	 * 任务执行入口
	 */
	public void run() {
		LoginQQ login = new LoginQQ(gui);
		
		HttpPost httppost = new HttpPost("http://d.web2.qq.com/channel/poll2");
		
		try {
			log.debug(qqNumVO.getQqNum() + "发送心跳包线程执行");

			for (int i = 0; i < Constant.ALREADY_LOGIN_QUEEN.size(); i++) {
				if (Constant.ALREADY_LOGIN_QUEEN.get(i).getQqNum()
						.equals(qqNumVO.getQqNum())) {
					Constant.ALREADY_LOGIN_QUEEN.get(i)
							.setSentPollResponse(null);
				}
			}

			// 设置http头信息
			httppost.setHeader("Accept", "*/*");
			httppost.setHeader("Accept-Encoding", "gzip, deflate");
			httppost.setHeader("Accept-Language", "zh-cn");
			httppost.setHeader("Cache-Control", "no-cache");
			httppost.setHeader("Connection", "Keep-Alive");
			httppost.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			httppost.setHeader("Host", "d.web2.qq.com");
			httppost.setHeader("Referer",
					"http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=3"); // 一定要这一个，如果不是会出现103错误
			httppost.setHeader("User-Agent",
					"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");

			List<NameValuePair> params = new ArrayList<NameValuePair>();

			params.add(new BasicNameValuePair("clientid", "50705043"));
			params.add(new BasicNameValuePair("psessionid", psessionid));
			params.add(new BasicNameValuePair("r",
					"{\"clientid\":\"50705043\",\"psessionid\":\""
							+ psessionid + "\",\"key\":0,\"ids\":[]}"));

			UrlEncodedFormEntity encodeParams = new UrlEncodedFormEntity(
					params);

			log.debug(qqNumVO.getQqNum() + "心跳包数据：" + EntityUtils.toString(encodeParams));

			httppost.setEntity(encodeParams);
			
			HttpResponse response = qqNumVO.getHttpClient().execute(httppost);
			
			if(!Constant.QQ_LIST.get(qqNumVO.getQqNum()).isLogin()){
				return;
			}
			
			// 获取响应实
			HttpEntity entity = response.getEntity();

			String responseString = EntityUtils.toString(entity,
					"UTF-8");

			for (int i = 0; i < Constant.ALREADY_LOGIN_QUEEN.size(); i++) {
				if (Constant.ALREADY_LOGIN_QUEEN.get(i).getQqNum()
						.equals(qqNumVO.getQqNum())) {
					Constant.ALREADY_LOGIN_QUEEN.get(i)
							.setSentPollResponse(responseString);
				}
			}

			log.debug("QQ：" + qqNumVO.getQqNum() + "发送心跳包的返回："
					+ responseString);

			if (responseString.contains("{\"retcode\":103")
					|| responseString.contains("{\"retcode\":108")
					|| responseString.contains("{\"retcode\":114")
					|| responseString.contains("{\"retcode\":121")) {
				
				if(!qqNumVO.isLogin()){
					return;
				}
				
				login.updateStatus(qqNumVO.getIndex(),qqNumVO.getQqNum(), "掉线");
				login.updateOptStatus(qqNumVO.getIndex(),qqNumVO.getQqNum(), "掉线");
				
				Constant.QQ_LIST.get(qqNumVO.getQqNum()).setLogin(false);
				
				//从已登录列表中移除
				Iterator<QQNumVO> i = Constant.ALREADY_LOGIN_QUEEN.iterator();

				while (i.hasNext()) {
					if (i.next().getQqNum().equals(qqNumVO.getQqNum())) {
						i.remove();
					}
				}

				Constant.LOGIN_COUNT = Constant.ALREADY_LOGIN_QUEEN.size();
				
				login.updateAlreadyLogin(Integer.toString(Constant.ALREADY_LOGIN_QUEEN
						.size()));
				
				if(Constant.SEIZE){
					log.debug("自动抢线");
					login.updateOptStatus(qqNumVO.getIndex(),qqNumVO.getQqNum(), "掉线重新登录...");
					//添加到等待队列中
					Constant.LOGIN_QUEEN.add(qqNumVO);
					login.updateWaitingLogin(Integer.toString(Constant.LOGIN_QUEEN.size()));
					
//					reLogin(httpclient, qq);
				}
			}
		} catch (Exception he){
//			if(!he.getMessage().contains("Read timed out")){
//				he.printStackTrace();
//			}
			
			log.error(qqNumVO.getQqNum() + "心跳包连接超时");
			
			httppost.abort();
			httppost.releaseConnection();
			
			for (int i = 0; i < Constant.ALREADY_LOGIN_QUEEN.size(); i++) {
				if (Constant.ALREADY_LOGIN_QUEEN.get(i).getQqNum()
						.equals(qqNumVO.getQqNum())) {
					Constant.ALREADY_LOGIN_QUEEN.get(i)
							.setSentPollResponse("");
				}
			}
			
			return;
		}
		this.finishTime = new Date();
	}

	/**
	 * 
	 * 方法概述：获取时间戳 
	 * 描述：获取时间戳
	 * 
	 * @return 
	 * 返回类型：long 
	 * 修改人：梁铭显 
	 * 修改时间：2012-9-10
	 */
	public long getUTCTime() {
		return System.currentTimeMillis();
	}
	
	public Date getGenerateTime() {
		return generateTime;
	}

	public Date getBeginExceuteTime() {
		return beginExceuteTime;
	}

	public void setBeginExceuteTime(Date beginExceuteTime) {
		this.beginExceuteTime = beginExceuteTime;
	}

	public Date getFinishTime() {
		return finishTime;
	}

	public void setFinishTime(Date finishTime) {
		this.finishTime = finishTime;
	}

	public Date getSubmitTime() {
		return submitTime;
	}

	public void setSubmitTime(Date submitTime) {
		this.submitTime = submitTime;
	}

	public long getTaskId() {
		return taskId;
	}

	public void setTaskId(long taskId) {
		this.taskId = taskId;
	}

}
